﻿using System.Collections.Generic;
using System.ServiceModel;
using StockholmsStad.Runtime.Serialization.DataContract;
using StockholmsStad.Runtime.Serialization.DataContract.Enums;

namespace StockholmsStad.ServiceModel.Interfaces
{
    /// <summary>
    /// Alla tjänster mot webgränssnittet
    /// </summary>
    [ServiceContract]
    public interface IWebService
    {
        /// <summary>
        /// Hämta ceremonispråken
        /// </summary>
        /// <returns>En lista med LanguageId och LanguageName</returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IList<ValueIdPair> GetCeremonyLanguages(User user);

        /// <summary>
        /// Hämta certifikatspråken
        /// </summary>
        /// <returns>En lista med LanguageId och LanguageName</returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IList<ValueIdPair> GetWeddingCertificateLanguages(User user);

        /// <summary>
        /// Hämta hjälpmedel för ceremoni
        /// </summary>
        /// <returns>En lista med SpecialNeedId och SpecialNeedName</returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IList<ValueIdPair> GetCeremonySpecialNeeds(User user);

        /// <summary>
        /// Hämta ceremonytyper, typ ordinarie i stadshuset och individuell på annan plats
        /// </summary>
        /// <returns>En lista med CeremonyTypeId och CeremonyTypeName</returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IList<ValueIdPair> GetCeremonyTypes(User user);

        /// <summary>
        /// Skapar ett nytt ärende för aktuellt par och dess önskemål om ceremoni
        /// </summary>
        /// <param name="couple">Information om paret</param>
        /// <param name="ceremony">Information om ceremonin</param>
        /// <returns>Ärendenumret</returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        int RegisterCouple(Couple couple, Ceremony ceremony);

        /// <summary>
        /// Uppdaterar ett ärende
        /// </summary>
        /// <param name="user"></param>
        /// <param name="couple"></param>
        /// <param name="ceremony"></param>
        /// <param name="ticketId"></param>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        void UpdateCouple(User user, Couple couple, Ceremony ceremony, int ticketId);

        /// <summary>
        /// Sparar en bokning för ett par. Operationen kan skapa, ta bort och förändra bokning
        /// </summary>
        /// <param name="user"></param>
        /// <param name="booking"></param>
        /// <param name="ticketId"></param>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        void SaveBooking(User user, Booking booking, int ticketId);

        /// <summary>
        /// Avbokar en bokning för ett par. 
        /// </summary>
        /// <param name="user"></param>
        /// <param name="ticketId"></param>
        /// <param name="booking"></param>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        void CancelBooking(User user, int ticketId, Booking booking);

        /// <summary>
        /// Hämta bokning
        /// </summary>
        /// <param name="user"></param>
        /// <param name="ticketId">Ärende-id för den bokning som ska avbokas.</param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        Booking GetBooking(User user, int ticketId);

        /// <summary>
        /// Hämta ärende
        /// </summary>
        /// <param name="user"></param>
        /// <param name="ticketId"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        Ticket GetTicket(User user, int ticketId);

        /// <summary>
        /// Hämta ärendeid-numret för det inloggade paret
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        int GetTicketId(User user);

        /// <summary>
        /// Kontrollera om bokningskod finns för en förättare
        /// </summary>
        /// <param name="user"></param>
        /// <param name="bookingCode"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        bool IsBookingCodeValid(User user, string bookingCode);

        ///<summary>
        /// Kontrollerar att användaren får logga in på webben
        ///</summary>
        ///<param name="username"></param>
        ///<param name="password"></param>
        ///<returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        bool IsValidWebUser(string username, string password);

        /// <summary>
        /// Hämtar en användare
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        User GetUser(string username);

        /// <summary>
        /// Hämtar alla bokade dagar, dvs det första tidblocket för en dag
        /// som inte har några lediga tider. Enbart dagar som ligger efter dagens datum returneras
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IEnumerable<TimeBlock> GetBookedTimeBlockDates(User user);

        /// <summary>
        /// Hämtar alla lediga tidblock från dagens datum
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        List<TimeBlock> GetFreeTimeBlockDateTimes(User user, bool ordinary);

        /// <summary>
        /// Returnerar true om användarnamnet är unikt
        /// </summary>
        /// <param name="user"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        bool IsUserNameUnique(User user, string username);

        /// <summary>
        /// Returnerar true om bokningen kan uppdateras från webbapplikationen
        /// </summary>
        /// <param name="booking"></param>
        /// <returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        bool IsUpdateable(Booking booking);

        ///<summary>
        /// Hämtar alla historikloggar för användaren.
        ///</summary>
        ///<param name="user"></param>
        ///<returns></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IList<History> GetHistoryForCurrentUser(User user);

        ///<summary>
        /// Skickar ett mail till användaren med det befintliga lösenordet
        ///</summary>
        ///<param name="email">E-postadressen dit användarinformationen ska skickas. </param>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        void SendForgottenPassword(string email);

        /// <summary>
        /// Hämtar alla texter av en viss typ. 
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <param name="textTypeId">Den typ av text som ska hämtas. </param>
        /// <returns>En lista med texter. </returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        IList<InformationText> GetTexts(User user, int textTypeId);

        /// <summary>
        /// DUMMY metod för att enumen InformationTextType ska genereras till klienten 
        /// </summary>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        InformationTextType GetInformationTextTypeDUMMY();

        /// <summary>
        /// Operationskontrakt som hämtar databasens version.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>En version <see cref="StockholmsStad.Data.Entity.Version"/></returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        string GetDatabaseVersion(User user);

        /// <summary>
        /// Operationskontrakt som hämtar tjänstelagrets version.
        /// </summary>
        /// <param name="user">Den inloggade användaren (<see cref="User"/>).</param>
        /// <returns>Ett versionsnummer </returns>
        [OperationContract]
        [FaultContract(typeof(ExceptionDetail))]
        string GetServiceVersion(User user);
    }
}
